/**
  ******************************************************************************
  * @file    app_X-CUBE-DPower.h
  * @author  STMicroelectronics
  * @version 1.0.0
  * @date    06-Jun-2022
  * @brief   Application program header
  * @details This application example is a Buck PSU converter
  ******************************************************************************
  *
  * Copyright (c) 2019 Biricha Digital Power Limited
  * Copyright (c) 2021(-2022) STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file in
  * the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  ******************************************************************************
  */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __APP_DIGITALPOWER_H
#define __APP_DIGITALPOWER_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "math.h"
#include "stm32g4xx_hal.h"
#include "stm32_hal_legacy.h"
#include "DPC_Miscellaneous.h"

#include "DPC_Pid.h"
#include "dpwr_dcdc.h"

/* Exported types ------------------------------------------------------------*/
typedef struct G4_Demo_t {
	uint32_t periodBuck;    // Number of ticks per period, read from the hrtim register
	uint32_t periodBoost;   // Number of ticks per period, read from the hrtim register
	uint8_t NbrActiveLoad;  // Memorizes the number of active Resistors load
} G4_Demo_t;
extern G4_Demo_t      Demo;
extern DCDC_DataFloat myDcdc;
extern CNTRL_3p3zDataFloat vLoop;                          /**< The voltage loop controller (if used) */
extern CNTRL_3p3zDataFloat iLoop;                          /**< The current loop controller (if used) */

extern uint16_t       bPowerUp;
extern LED_Status_t  LED_GREEN_Status;    /* Green LED status */
extern LED_Status_t  LED_RED_Status;      /* Red LED status */
extern LED_Status_t  LED_BLUE_Status;     /* Blue LED status */
extern LED_Status_t  LED_ORANGE_Status;   /* Orange LED status */
extern uint16_t      LED_LastFaultShown;  /* last DCDC fault shown with LED blinking */

/* Exported macro ------------------------------------------------------------*/
#define FREQ_HZ_TO_PWM_TICKS(f)            ((uint16_t)(HRTIM_CLK_HZ / f))
#define NS_TO_PWM_TICKS(n)                 ((uint16_t)((HRTIM_CLK_HZ * n) / 1000000000))

/* Convert a delay in ns to HRTIM ticks */
#define DELAY_NS_2_HRTIM_TICKS(x)          ((uint16_t)((x * HRTIM_CLK_MHZ)/1000))
#define DELAY_NS_2_HRTIM_TICKS_SIGNED(x)   ((int16_t)((x * HRTIM_CLK_MHZ)/1000))
#define DELAY_NS_2_TIMx_TICKS(x)           ((uint16_t)((uint32_t)((uint32_t)x * (uint32_t)TIMx_CLK_MHZ)/1000LL))

/* Exported constants --------------------------------------------------------*/
/* -- User's Modalities ----------------------------------------------------- */
#define OVERVOLTAGE_PROTECTION          true   /* When defined, Enable the OVP mechanism (=> DC/DC is disabled) when the output voltage is above the threshold */
#define SHORT_CIRCUIT_PROTECTION        true   /* When defined, Enable the UVP mechanism (=> DC/DC is disabled) when the output voltage is below the threshold */
/* -- User's Debug ---------------------------------------------------------- */
//#define DEBUG_MODE                         /* When defined, SR delays and Phase-shift value are set via debugger - State Machine is moved through debugger */
//#define DEBUG_COMP_OUT                     /* When defined, Enable COMP2 output usage for debug */
//#define RUN_OPEN_LOOP                      /* When defined, System runs in open loop to allow PWM tuning - WARNING : Over Voltage maybe output with damage components or electric shock strong effects */
//#define PLOT_WAVEFORM                      /* When defined, Plot waveform using the IAR IDE */

/* -- MCU PARAMETERS -------------------------------------------------------- */
/* Clocks frequencies */
/* if prescaler = 0 -> f_HRCK = 170x32MHz = 5.44GHz, res = 184ps, min_PWM_freq = 83.0kHz
   if prescaler = 1 -> f_HRCK = 170x16MHz = 2.72GHz, res = 368ps, min_PWM_freq = 41.5kHz
   if prescaler = 2 -> f_HRCK = 170x8MHz = 1.36GHz, res = 735ps, min_PWM_freq = 20.8kHz
   It is needed to align HRTIM_CLK_HZ and HRTIM_PRESC_RATIO accordingly with SWITCHING_FREQ_HZ */
#define HRTIM_CLK_HZ                     ((uint32_t)5440000000)      /* Frequency in Hz of HRTIM clock - prescaler = 0 */
#define TIMx_CLK_HZ                      ((uint32_t)170000000)       /* Frequency in Hz of TIMx clock used for COMP blanking window (OCP) */

/* PWM frequencies */
#define HRTIM_PWM_PERIOD                   FREQ_HZ_TO_PWM_TICKS(SWITCHING_FREQ_HZ)
#define HALF_HRTIM_PWM_PERIOD              (uint16_t)(HRTIM_PWM_PERIOD/2)
#define HRTIM_CLK_MHZ                      ((uint16_t)(HRTIM_CLK_HZ/1000000))  /* Frequency in MHz of HRTIM clock */

/* Blanking window for OCP */
#define BLANKING_WINDOW_DURATION_NS        ((uint16_t)(DEAD_TIME_RISING_NS + 1000))  /* Blanking window duration for COMPx in ns, this value must consider dead time */

/* Convert Blanking window time in TIMx ticks */
#define TIMx_CLK_MHZ                       ((uint16_t)(((uint32_t)(TIMx_CLK_HZ))/1000000LL))
#define BLANKING_WINDOW_DURATION_TIMx_TICK   DELAY_NS_2_TIMx_TICKS(BLANKING_WINDOW_DURATION_NS)

/* -- Burst Mode ------------------------------------------------------------ */
// PBo - Used only with STM32F334 ?!?
#define BURST_MODE_IDLE_DURATION           10                 /* When OUT_VOLTAGE_BURST_MODE is defined, it is the number of idle periods during burst mode activation */
#define BURST_MODE_PERIOD                  10                 /* When OUT_VOLTAGE_BURST_MODE is defined, it is the number of idle+run periods during burst mode activation */

/* -- Tasks Execution Frequencies ------------------------------------------- */
/* Switching frequency is the same as the fast loop ISR frequency */
#define SWITCHING_FREQ_HZ                  ((uint32_t)(200000))             /* Frequency in Hz of PWM signals */

/* Voltage Control loop frequency */
#define VOLTAGE_CONTROL_LOOP_FREQ          ((uint16_t)(6300))  /* Execution frequency of Vout control loop (choose a submultiple of PWM frequency) */
#define HRTIM_REP_RATE                     ((uint8_t)((SWITCHING_FREQ_HZ/VOLTAGE_CONTROL_LOOP_FREQ) - 1))  /* Repetition rate of HRTIM */

/* -- Timings parameters ---------------------------------------------------- */
#define STARTUP_DCDC_RAMP_DURATION         ((uint16_t)(2000))   /* Duration in ms of the ramp up */
#define WAIT_DCDC_TIME_DURATION            ((uint16_t)(1000))   /* Duration in ms of status DCDC_WAIT after DCDC_FAULT before entering in DCDC_IDLE state */

/* Dead time configuration */
#define DEAD_TIME_RISING_NS                ((uint16_t)(430))     /* Dead time of rising edge in ns */
#define DEAD_TIME_FALLING_NS               ((uint16_t)(450))    /* Dead time of falling edge in ns */
/* Convert Dead time delay in HRTIM ticks (dead time registers have another conversion) */
#define DEAD_TIME_RISING_HR_TICK           DELAY_NS_2_HRTIM_TICKS(DEAD_TIME_RISING_NS)
#define DEAD_TIME_FALLING_HR_TICK          DELAY_NS_2_HRTIM_TICKS(DEAD_TIME_FALLING_NS)

/* if prescaler = 3 then fDTG = fHRTIM -> t_DTG = 8.882ns, , DTmax = 511*t_DTG = 3.0058us */
#define DEAD_TIME_RISING_DT_TICK     ((uint32_t)((DEAD_TIME_RISING_NS * 170)/1000))
#define DEAD_TIME_FALLING_DT_TICK    ((uint32_t)((DEAD_TIME_FALLING_NS * 170)/1000))
#define DEAD_TIME_PRESCALER          HRTIM_TIMDEADTIME_PRESCALERRATIO_DIV1

/* LED status Blinking */
#define LED_BLINK_REPETITION_PERIOD_MS     3000
#define LED_BLINK_PERIOD_MS                500
#define LED_BLINK_PERIOD_SHORT_MS          200
#define LED_BLINK_PERIOD_LONG_MS           1000
#define LED_STARTUP_BLINK_NUM              1
#define LED_RUN_BLINK_NUM                  2
#define LED_OVERVOLTAGE_BLINK_NUM          3
#define LED_SHORTCIRCUIT_BLINK_NUM         4
#define LED_OVERCURRENT_BLINK_NUM          5
#define LED_OVERTEMPERATURE_BLINK_NUM      6
#define LED_ERROR_BLINK_NUM                7

/* -- User's Parameters ----------------------------------------------------- */
/* Voltage regulation value */
#define NOMINAL_IN_VOLTAGE                 IN_VOLT_ADC_VALUE(5.0)               /* Nominal input voltage in Volts */
#define NOMINAL_OUT_VOLTAGE                OUT_VOLT_ADC_VALUE(48.0)             /* Nominal output voltage in Volts */
#define STARTUP_FINAL_OUT_VOLTAGE          NOMINAL_OUT_VOLTAGE               /* Voltage reference after start-up */

/* The procedure for designing the digital filter was described
 * in the workshop lectures. We used the ST-WDS to calculate the required poles
 * and zeros and then the web-tools to calculate the coefficients.
 */
#define DAC_OVERCURRENT_THRESHOLD          ((uint16_t) (4095))   /* Output OCP level */
#define MIN_OUT_VOLTAGE_SHORT_CIRCUIT      OUT_VOLT_ADC_VALUE(30)            /* Min output voltage if SHORT_CIRCUIT_PROTECTION is defined */

/* Coefficients for a 200kHz power supply at 170MHz */
/* The voltage reference is given in ADC units (this is, a value between) 0 and 4095,
 * which corresponds to a voltage between 0 and 3.3V using onboard scaling factor.
 *
 * This potential divider applies a factor of 0.198 to the output voltage.
 * We want a Vout=+3.3V => (3.3 * 0.198 * (4095 / 3.3)) = 810.81
 */
#define REF (3163)

/* P&Z controller using the CPU */
/* Control loop with very low crossover */
/* Fx: 7.33 kHz  Pm: 61 degrees  Gm: 48 dB  Slope@Fx: -25.5 dB/dec */
#define B0 (0x84D)
#define B1 (0xF7CE)
#define B2 (0xF7B3)
#define B3 (0x832)
#define A1 (0x5F99)
#define A2 (0xA0CD)
#define A3 (0x1F9A)

/* K scaling factor from ST-WDS */
#define K  (500.0)

/* Duty cycle range */
#define DUTY_TICKS_MIN (60)   /* Min duty when using High Resolution timer */
#define DUTY_TICKS_MAX (24480)   /* Max duty when using High Resolution timer */

/* -- ADC Converting Macros: Volts, Ampere to ADC measure ------------------- */
/* ADC Scaling -> (12 bit / Vref) */
#define GADC                              (1240.909090)       // (4095.0f/3.3f) = 1240.909090f

/* Input Voltage */
#define IN_VOLT_CONV_RATIO                (0.20118343)       /* Input DC bus voltage partitioning ratio : (6.8k / (6.8k + 27k)) */
#define IN_VOLT_ADC_VALUE(v)              ((uint16_t)(v * IN_VOLT_CONV_RATIO * GADC))

/* Output Voltage */
#define OUT_VOLT_CONV_RATIO               (0.057591623)       /* DC bus voltage partitioning ratio : (3.3k/(3.3k + 13.3k)) */
#define OUT_VOLT_ADC_VALUE(v)             ((uint16_t)(v * OUT_VOLT_CONV_RATIO * GADC))

/* Current Transformer Sensing (CTS) */
#define BRIDGE_CURR_CONV_RATIO            (0.235910878)       /* (1/250) * (1/(1/5100 + 1/187)) */
#define BRIDGE_CURR_ADC_VALUE(i)          ((uint16_t)(i * BRIDGE_CURR_CONV_RATIO * GADC))

/* Private defines -----------------------------------------------------------*/
/* Exported functions prototypes ---------------------------------------------*/
void LoadHandler(void);
void MX_X_CUBE_DPower_Init(void);
void MX_X_CUBE_DPower_Process(void);

#ifdef __cplusplus
}
#endif

#endif /* APP_DIGITALPOWER_H */
